<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.global.js"></script>
</head>

<body>
    <div id="app">
        <p ref="demo">{{count}}</p>
        <p><button @click="addCount">count++</button></p>
    </div>
</body>
<script>

    // 组合式 API 的核心思想是直接在函数作用域内定义响应式状态变量，并将从多个函数中得到的状态组合起来处理复杂问题

    let { createApp ,getCurrentInstance,onMounted} = Vue;
    let { ref,watch } = Vue;


    let app = createApp({
        setup(props) {

            // ref()  => 创建一个对"值类型"数据的引用,返回一个ref对象 (存对象类型也可以)
            // 注意:
            // 1. setup函数中对ref对象取值和赋值 依赖于.value属性
            // 2. 代理对象中 / template中 ref对象会被解包 => 直接使用变量即可
            // 3. ref() 也可以存对象类型, 此时Vue响应式对ref数据的数据拦截是深层的(可以检测value值是否改变,也可以检测子对象上属性是否改变 => 触发视图更新)

            let count = ref(10);  // {value:10}

            let cur = getCurrentInstance();

            let demo = ref(null);  // !! 1.  一定要暴露出去  2. 在页面挂载完毕之后使用
           

            addCount = () => {
                count.value++;
            }


            // watch(source, callback, option)
            // 第三参数 option中存在flush选项 => 可以控制callback执行的时机
            // flush: sync/pre(默认)/post
            //     sync: 数据改变之后立即执行
            //     pre: 数据改变,视图更新之前执行
            //     post: 数据改变,且视图更新之后执行 

            /* watch(count,(newVal,oldVal)=>{

                // 组合式语法中 对应ref名获取元素  
                // 1. 通过当前组件实例获取 (a. 获取当前组件实例  2. 组件实例的refs对象对应ref名获取元素)
                // let demo = cur.refs.demo;
                // console.log(2222, demo); // demo => 原生dom元素


                // 2. 对应ref名获取元素
                // a. 对应ref名通过ref()方法创建一个变量 => 暴露出去
                // b. 等页面挂载完毕  ref对象的中的value值会被替换对应的元素
                // console.log(demo.value.innerHTML);


                // 数据改变后之后视图不会立即更新, 想获取更新后dom元素的内容

                // 1. nextTick
                // let ctx = cur.ctx;
                // ctx.$nextTick(()=>{ // 
                //     console.log(demo.value.innerHTML);
                // })

                console.log(demo.value.innerHTML);


            },{flush:"post"}) // 数据改变,且视图更新之后执行回调函数 */


            watch(count,(newVal,oldVal)=>{
                console.log(1);
            },{flush:"sync"}) 

            watch(count,(newVal,oldVal)=>{
                console.log(2);
            },{flush:"pre"}) 

            watch(count,(newVal,oldVal)=>{
                console.log(3);
            },{flush:"post"}) 


            return {
                count: count,
                addCount,
                demo,
            }
        },
        mounted() {
            console.log("代理对象,this", this);


        },
    })


    app.mount("#app");


</script>

</html>